/*
 * @Author: your name
 * @Date: 2021-09-16 20:09:09
 * @LastEditTime: 2022-01-14 14:36:45
 * @LastEditors: xuesong
 * @Description: In User Settings Edit
 * @FilePath: \BLE-SDK-SVN499-V03\projects\ble_peripheral\uart_ble\src\Remote\User_keyScan.c
 */

#include "User_keyScan.h"
#include "OSAL.h"
#include "log.h"
#include "halPeripheral.h"
#include "simpleBLEPeripheral.h"
#include "gpio.h"


// uint8   KeyDownTrage = 0;
// uint8   KeyUpTrage = 0;


// void wakeup_pin_hdl(GpioPin_t pin,gpio_polarity_e type)
// {
//     if(pin == WAKEUP_PIN)
//     {
//         peripheral_task_set(TASK_ACTION_START,USR_WAKEUP_PIN_DET, PIN_DEBONCE_TIME);
//     }
// }

void KeyPinInt(void)
{

    HalGpioPinInit(KeyOnOffPin, GPIO_INPUT);
    HalGpioPupdConfig(KeyOnOffPin, GPIO_PULL_UP);

    HalGpioPinInit(KeyChargPin, GPIO_INPUT);
    HalGpioPupdConfig(KeyChargPin, GPIO_PULL_UP);

    HalGpioPinInit(KeyFullPin, GPIO_INPUT);
    HalGpioPupdConfig(KeyFullPin, GPIO_PULL_UP);
}

void hal_gpio_wakeup_control(GpioPin_t pin, bit_action_e value);
void KeyPowerDown(void)
{
    // hal_gpio_wakeup_control(KeyUnitPin,Bit_DISABLE);
    // hal_gpio_wakeup_control(KeyTarePin,Bit_DISABLE);
    // hal_gpio_wakeup_control(KeyCDTimerPin,Bit_DISABLE);
    // hal_gpio_wakeup_control(KeyModePin,Bit_DISABLE);
    // hal_gpio_wakeup_control(KeyShortCutPin,Bit_DISABLE);
}

KeyFlag_t GetKeyBits(void)
{
    KeyFlag_t tempKeyTrage ={
        .flagByte = 0,
    };
    if(!HalGpioGet(KeyOnOffPin))
        tempKeyTrage.flagBit.onOff = true;     
    if(!HalGpioGet(KeyFullPin))
        tempKeyTrage.flagBit.ChargFull = true;
    if(!HalGpioGet(KeyChargPin))
        tempKeyTrage.flagBit.Charg = true; 
    return tempKeyTrage;
}
/**
 * @brief 
 * @param  TempKeyStatus          MyParamDoc
 *          .Trage InPut
 */
void KeyScan(KeyStatus_t *TempKeyStatus)
{
#define KEY_LONG_TIME 64    // 2s
#define KEY_SHORT_TIME 2    // 0.064S
#define KEY_OUT_LONG_TIME 8 // 0.32S

    static KeyType_t KeyLTraged = 0;  // Continuou
    static KeyType_t KeyLFTraged = 0; // Fast Continuou
    static KeyType_t KeyReleaseCnt[sizeof(KeyType_t)*8] = {0};
    static KeyType_t KeyLongCnt[sizeof(KeyType_t)*8] = {0};
    static KeyType_t KeyLongFastCnt[sizeof(KeyType_t)*8] = {0};

    KeyType_t CurrentKeyBitFlag = 0;

    TempKeyStatus->LongTrage.flagByte = 0;
    TempKeyStatus->ShortTrage.flagByte = 0;
    TempKeyStatus->LongFastTrage.flagByte = 0;
    for (uint8_t i = 0; i < (sizeof(KeyType_t)*8); i++)         //clr click time cont
    {
        CurrentKeyBitFlag = (0x01 << i);
        if(TempKeyStatus->ReleaseTrage.flagByte & CurrentKeyBitFlag)
            TempKeyStatus->ClikckCnt[i] = 0;            
    }
    TempKeyStatus->ReleaseTrage.flagByte = 0;

    CurrentKeyBitFlag = TempKeyStatus->Trage.flagByte;
    // LOG("readkey=%X\n",CurrentKeyBitFlag);
    
    TempKeyStatus->Trage.flagByte = (CurrentKeyBitFlag & (TempKeyStatus->Cont.flagByte ^ CurrentKeyBitFlag));
    if (TempKeyStatus->Trage.flagByte)
    {
        LOG("C=%X,T=%X\n",TempKeyStatus->Cont.flagByte, TempKeyStatus->Trage.flagByte);
    }
    TempKeyStatus->Cont.flagByte = CurrentKeyBitFlag;

    // TempKeyStatus.Trage.flagByte = 0;
    for (uint8_t i = 0; i < (sizeof(KeyType_t)*8); i++)
    {
        CurrentKeyBitFlag = (0x01 << i);
        if (TempKeyStatus->Cont.flagByte & CurrentKeyBitFlag)
        {
            KeyLongCnt[i]++;
            KeyReleaseCnt[i] = 0;

            // if (KeyLongCnt[i] >= KEY_SHORT_TIME && !(KeyLTraged & CurrentKeyBitFlag))        //释放有效
            //     TempKeyStatus->Trage.flagByte |= CurrentKeyBitFlag;

            if(TempKeyStatus->Trage.flagByte & CurrentKeyBitFlag)
                TempKeyStatus->ClikckCnt[i] ++;
        }
        else
        {
            KeyReleaseCnt[i]++;
            if(KeyReleaseCnt[i] > KEY_OUT_LONG_TIME && TempKeyStatus->ClikckCnt[i])
            {
                KeyReleaseCnt[i] = 0;
                TempKeyStatus->ReleaseTrage.flagByte |= CurrentKeyBitFlag;
            }
            if (!(KeyLTraged & CurrentKeyBitFlag))
            {
                if (KeyLongCnt[i]) // Relase for key out
                    TempKeyStatus->ShortTrage.flagByte |= CurrentKeyBitFlag;
            }else{
                TempKeyStatus->ClikckCnt[i] = 0;                                                //长按输出过不算快击
            }
            KeyLongCnt[i] = 0;
            KeyLongFastCnt[i] = 0;
            KeyLTraged &= ~CurrentKeyBitFlag;
            KeyLFTraged &= ~CurrentKeyBitFlag;
        }

        // if(KeyLongCnt[i] > KEY_LONG_TIME && !(KeyLTraged & CurrentKeyBitFlag)){
        //     TempKeyStatus.LongTrage |= CurrentKeyBitFlag;
        //     KeyLTraged |= CurrentKeyBitFlag;
        // }

        uint8_t LongTimeOut = KEY_LONG_TIME;
        if (KeyLTraged & CurrentKeyBitFlag)
            LongTimeOut = KEY_OUT_LONG_TIME;
        if (KeyLFTraged & CurrentKeyBitFlag)
            LongTimeOut = (KEY_OUT_LONG_TIME>>2);

        if (KeyLongCnt[i] > LongTimeOut)
        {
            if (!(KeyLTraged & CurrentKeyBitFlag))
                TempKeyStatus->LongTrage.flagByte |= CurrentKeyBitFlag;
            TempKeyStatus->LongFastTrage.flagByte |= CurrentKeyBitFlag;
            KeyLongCnt[i] = 0;
            KeyLongFastCnt[i]++;
            if(KeyLongFastCnt[i] > 5)
                KeyLFTraged |= CurrentKeyBitFlag;
            KeyLTraged |= CurrentKeyBitFlag;
        }
    }
}

/**
 * @brief  find litter input checkBit Relese clicktimes
 * @param  CheckBit         
 * @param  Key              MyParamDoc
 * @return uint8_t 
 */
uint8_t CheckKeyClickTimes(KeyFlag_t CheckBit,const KeyStatus_t* const Key)
{
    uint8_t clickTimes = 0;
    KeyType_t CurrentKeyBitFlag = 0;
    for (uint8_t i = 0; i < (sizeof(KeyType_t)*8); i++)
    {
        CurrentKeyBitFlag = (0x01 << i);
        if(CurrentKeyBitFlag & CheckBit.flagByte)
        {
            clickTimes = Key->ClikckCnt[i];
            break;
        }
    }
    return clickTimes;
}

